package cn.woblog.android.downloader.thread;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import cn.woblog.android.downloader.db.DBController;
import cn.woblog.android.downloader.domain.DownloadInfo;
import cn.woblog.android.downloader.domain.DownloadStatus;
import cn.woblog.android.downloader.exception.ObtainFileSizeException;
import cn.woblog.android.downloader.listener.DownloadListener;
import cn.woblog.android.downloader.observable.DataChanger;
import cn.woblog.android.downloader.utils.Consts;
import cn.woblog.android.downloader.utils.FileUtils;
import cn.woblog.android.downloader.utils.MyLog;

public class DownloadTask implements DownloadListener {

	private Context context;
	private DownloadInfo info;
	private Handler handler;
	private cn.woblog.android.downloader.thread.DownloadThread downloadThread;
	private long currentProgress;
	private DataChanger dataChanger;
	private DBController dbController;

	public DownloadTask(Context context, DownloadInfo info, Handler handler) {
		this.context = context;
		this.info = info;
		this.handler = handler;
		currentProgress = info.getProgress();
		dataChanger = DataChanger.getInstance(context);
		dbController = DBController.getInstance(context);
	}

	public void start() {
		info.setStatus(DownloadStatus.GET_SIZEING);
		new GetFileLengthTask().execute((Void) null);
	}

	class GetFileLengthTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected Void doInBackground(Void... arg0) {
			long fileSize;
			try {
				fileSize = FileUtils.getFileSize(info.getUrl());
				MyLog.d("single file size：" + fileSize);
				info.setSize(fileSize);
			} catch (ObtainFileSizeException e) {
				info.setStatus(DownloadStatus.GET_FILE_SIZE_ERROR);
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			startDownload();
		}

	}

	public void startDownload() {
		info.setStatus(DownloadStatus.DOWNLOADING);
		downloadThread = new DownloadThread(this, context, info, this);
		downloadThread.start();
	}

	@Override
	public void onDownloadProgressChanged(long l, DownloadInfo data) {
		dataChanger.addNotifiy(info);
		dbController.newOrUpdate(info);
	}

	@Override
	public void onDownloadComplete(DownloadInfo data) {
		MyLog.d("download done:" + data.getId());
		dataChanger.removeNotifiy(info.getId());
		dataChanger.notifyOne(data);
		info.setStatus(DownloadStatus.DONE);
		dbController.newOrUpdate(info);
		Message message = handler.obtainMessage(Consts.MSG_DOWNLOAD_COMPLETE,
				data.getId());
		handler.sendMessage(message);
	}

	public void pause(boolean pause) {
		downloadThread.pause(pause);
	}

	@Override
	public void onDownloadStatusChanged(DownloadInfo data) {
		MyLog.d("download status changed:" + data.getId() + ":"
				+ data.getStatus());
		dataChanger.notifyOne(data);
		dataChanger.addNotifiy(data);
		dbController.newOrUpdate(info);

		if (data.getStatus() == DownloadStatus.DELETE) {
			dataChanger.removeDownload(data.getId());
		}

		if (data.getStatus() == DownloadStatus.PAUSE
				|| data.getStatus() == DownloadStatus.DELETE) {
			handler.sendEmptyMessage(Consts.MSG_CHECK_NEXT);
		}
	}

	public void stop() {
		if (downloadThread != null) {
			downloadThread.setStop(true);
		}
	}

}
